<template>
  <div class="icons">
    <router-link to="/docs/" target="_blank">
      <div class="message-info-container">
        <a-tooltip title="用户手册">
          <a-icon-font class="message-icon" type="iconbangzhuwendang" />
        </a-tooltip>
      </div>
    </router-link>

    <a-popover
      class="popover-container"
      :get-popup-container="(triggerNode) => triggerNode.parentNode"
      placement="bottom"
    >
      <template slot="content" class="message-list">
        <a-tabs
          v-model="noticeType"
          :default-active-key="0"
          :tab-bar-gutter="0"
          :tab-bar-style="{ width: '100%', height: '44px' }"
          :style="{ top: '-10px' }"
          @change="handleChange"
        >
          <a-tab-pane :key="0" tab="未读" class="tab-panel">
            <a-list item-layout="horizontal" :data-source="unreadNoticeList">
              <a-list-item
                slot="renderItem"
                slot-scope="item"
                class="list-item"
              >
                <a-list-item-meta>
                  <div slot="title" class="notice-content">
                    <b
                      v-for="(textItem, index) in splitMessageContent(
                        item.content
                      )"
                      :key="index + '-' + item.id"
                      :style="{
                        fontWeight: textItem[1] === 1 ? 'bold' : 'normal',
                      }"
                    >
                      {{ textItem[0] }}
                    </b>
                  </div>
                  <div slot="title" class="notice-time">
                    {{ moment(item.gmtModify).format('YYYY-MM-DD HH:mm:ss') }}
                  </div>
                  <a-avatar slot="avatar" style="background-color: #eaeafd;">
                  </a-avatar>
                </a-list-item-meta>
                <!-- <router-link :to="`/project/${item.projectId}`"> -->
                <a-button
                  v-if="item.projectId"
                  class="notice-btn"
                  size="small"
                  @click="readMessage(item)"
                  >查看
                </a-button>
                <!-- </router-link> -->
              </a-list-item>
            </a-list>
          </a-tab-pane>
          <a-tab-pane :key="1" tab="已读" class="tab-panel">
            <a-list item-layout="horizontal" :data-source="readNoticeList">
              <a-list-item
                slot="renderItem"
                slot-scope="item"
                class="list-item"
              >
                <a-list-item-meta>
                  <div slot="title" class="notice-content">
                    <b
                      v-for="(textItem, index) in splitMessageContent(
                        item.content
                      )"
                      :key="index + '-' + item.id"
                      :style="{
                        fontWeight: textItem[1] === 1 ? 'bold' : 'normal',
                      }"
                    >
                      {{ textItem[0] }}
                    </b>
                  </div>
                  <div slot="title" class="notice-time">
                    {{ moment(item.gmtModify).format('YYYY-MM-DD hh:mm:ss') }}
                  </div>
                  <a-avatar slot="avatar" style="background-color: #eaeafd;">
                  </a-avatar>
                </a-list-item-meta>
                <!-- <router-link :to="`/project/${item.projectId}`"> -->
                <a-button
                  v-if="item.projectId"
                  class="notice-btn"
                  size="small"
                  @click="readMessage(item)"
                  >查看
                </a-button>
                <!-- </router-link> -->
              </a-list-item>
            </a-list>
          </a-tab-pane>
        </a-tabs>
        <router-link :to="'/user/messages'">
          <div class="message-footer">查看更多消息</div>
        </router-link>
      </template>
      <div>
        <router-link :to="'/user/messages'">
          <div class="message-info-container">
            <a-icon-font
              v-if="unreadNoticeList.length === 0"
              class="message-icon"
              type="iconxitongxiaoxishezhi"
            />
            <a-icon-font
              v-else
              class="message-icon"
              type="iconxitongxiaoxishezhibeifen"
            />
          </div>
        </router-link>
      </div>
    </a-popover>

    <a-dropdown
      :get-popup-container="(triggerNode) => triggerNode.parentNode"
      @visibleChange="
        (visible) => {
          dropdownIconType = visible ? 'up' : 'down'
        }
      "
    >
      <div class="user-info-container">
        <a-avatar
          slot="avatar"
          style="background-color: #eaeafd; margin-right: 8px;"
          :src="avatarUrl === null ? defaultAvatar : avatarUrl"
        >
        </a-avatar>
        <a-icon
          :type="dropdownIconType"
          style="
            color: #fff;
            font-size: 12px;
            transform: scale(0.83333333) rotate(0deg);
          "
        />
      </div>
      <a-menu slot="overlay" style="width: 225px;">
        <a-menu-item
          disabled
          style="align-items: center; display: flex; margin: 6px 8px;"
        >
          <a-avatar
            style="background-color: #eaeafd; margin-right: 8px;"
            :src="avatarUrl === null ? defaultAvatar : avatarUrl"
          >
          </a-avatar>
          <div style="width: 140px;">
            <div class="nickname">{{ nickname }}</div>
            <div class="username">{{ username }}</div>
          </div>
        </a-menu-item>
        <a-menu-item>
          <router-link to="/user/infos">
            <img class="drop-icon" alt="" src="@/assets/user/user.svg" />
            <span>个人信息</span>
          </router-link>
        </a-menu-item>
        <a-menu-item>
          <router-link to="/user/security-settings">
            <img class="drop-icon" alt="" src="@/assets/user/security.svg" />
            <span>账户安全</span>
          </router-link>
        </a-menu-item>
        <a-menu-item>
          <router-link to="/user/messages-settings">
            <img class="drop-icon" alt="" src="@/assets/user/message.svg" />
            <span>系统/消息设置</span>
          </router-link>
        </a-menu-item>
        <a-menu-item @click="() => (feedbackModalVisible = true)">
          <img class="drop-icon" alt="" src="@/assets/user/feedback.svg" />
          <span>意见反馈</span>
          <a-modal
            title="意见反馈"
            :visible="feedbackModalVisible"
            :confirm-loading="false"
            ok-text="提交"
            cancel-text="取消"
            @ok="handleFeedbackModalOk"
            @cancel="closeFeedbackModal"
          >
            <div>
              <p
                style="
                  color: #5d637e;
                  font-family: PingFangSC-Medium;
                  font-weight: 500;
                  letter-spacing: 1px;
                "
              >
                问题描述
              </p>
              <a-textarea
                v-model="feedbackTextarea"
                :auto-size="{ minRows: 3, maxRows: 6 }"
                placeholder="请输入问题描述 3-300字"
                :max-length="300"
              ></a-textarea>
              <p
                style="
                  color: #5d637e;
                  font-family: PingFangSC-Medium;
                  font-weight: 500;
                  letter-spacing: 1px;
                  margin-top: 1em;
                "
              >
                相关图片
              </p>
              <a-upload
                ref="uploadRef"
                multiple
                list-type="picture-card"
                :file-list="fileList"
                :before-upload="beforeUpload"
                :custom-request="customRequest"
                @preview="handlePreview"
                @change="handleChangeFileList"
              >
                <div v-if="fileList.length < 4">
                  <a-icon type="plus" />
                  <div class="ant-upload-text">Upload</div>
                </div>
              </a-upload>
              <div class="modal-subtext">
                支持JPG、PNG等格式，图片需小于2M
              </div>
              <a-modal
                :visible="previewVisible"
                :footer="null"
                @cancel="handleCancelPreview"
              >
                <img alt="example" style="width: 100%;" :src="previewImage" />
              </a-modal>
            </div>
          </a-modal>
        </a-menu-item>
        <a-menu-item @click="startUserGuide">
          <router-link to="/management/data">
            <img class="drop-icon" alt="" src="@/assets/user/guide.svg" />
            <span>新手指引</span>
          </router-link>
        </a-menu-item>
        <a-divider style="margin: 3px 0;"></a-divider>
        <a-menu-item @click="startUserGuide">
          <router-link to="/management/plugin/installed">
            <a-icon-font class="drop-icon" type="iconshequ-bendiyianzhuang" />
            <span>社区-本地已安装</span>
          </router-link>
        </a-menu-item>
        <a-divider style="margin: 3px 0;"></a-divider>
        <a-menu-item class="logout-item" @click="handleLogout">
          <a-icon type="export" />
          <span>退出</span>
        </a-menu-item>
      </a-menu>
    </a-dropdown>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from 'vue-property-decorator'
import UserStore from '@/store/modules/user'
import ProjectStore from '@/store/modules/project'
import DataStore from '@/store/modules/data'
import MessageStore from '@/store/modules/message'

import moment from 'moment'
import { saveFeedback } from '@/api/user'
import UserGuideStore from '@/store/modules/user-guide'

@Component({})
export default class InfoHeader extends Vue {
  public isMessageShow: boolean = false
  private feedbackModalVisible: boolean = false
  private previewVisible: boolean = false
  private feedbackTextarea: string = ''
  private previewImage: string = ''
  private fileList: any = []
  private hoverStyle = {
    background: '#2E3667',
  }
  private defaultAvatar: string = require('@/assets/user/avatar0.png')
  private dropdownIconType: any = 'down'

  private noticeType: number = 0 // 通知类型  0：未读，1.已读
  private timeoutTimes: number = 0 // token无效重试次数

  private get avatarUrl() {
    return UserStore.currentUser?.picEncode
  }

  private resetModalValue() {
    this.previewVisible = false
    this.feedbackTextarea = ''
    this.previewImage = ''
    this.fileList = []
  }

  public async created() {
    // 涉及后端接口问题，header不能太长，不然cookie会炸，后端会炸。
    // 所以这里改成了获取头像编码，获取头像不能用/auth/info和/login的接口
    // 只能用query的方式来获取头像编码
    if (UserStore.currentUser?.picEncode === null || !UserStore.currentUser) {
      await UserStore.queryUserInfo()
      await this.refreshViewValidationGuideStatus()
    }
    this.queryNoticeListInShortcut()
    this.initSocketEvent()
  }

  /**
   * 刷新页面 验证新用户引导状态 （解决新用户进入到用户引导页面刷新页面）
   * UserStore.currentUser?.guideStatus
   * 1 - 完成引导，
   * 0 - 未完成， info 接口的用户信息是 token 中解析出来的， 如果不重新 login 一直会是 0
   * 为 0 的时候，请求接口判断是否已经完成
   */
  public async refreshViewValidationGuideStatus() {
    if (UserStore.currentUser?.guideStatus === 0) {
      const result = await UserGuideStore.guideCheck(UserStore.currentUser.id)
      if (result === 0) {
        UserGuideStore.intoGuide()
      }
    }
  }

  public get nickname() {
    return UserStore.currentUser && UserStore.currentUser.nickName !== ''
      ? UserStore.currentUser.nickName
      : '-'
  }

  public get username() {
    return UserStore.currentUser ? UserStore.currentUser.name : ''
  }

  public get moment() {
    return moment
  }

  /**
   * 获取消息列表
   */
  public queryNoticeListInShortcut() {
    MessageStore.queryNoticeListInShortcut({
      pageNum: 1,
      pageSize: 10,
      status: this.noticeType,
    })
  }

  /**
   * 初始化socket相关事件
   */
  initSocketEvent() {
    this.timeoutTimes = 0
    this.registerToken()
    if (!this.$socket._callbacks.$register) {
      this.$socket.on('register', (data: any) => {
        // 110000,"缺少token"，110001,"无效token"，110002,"token过期"
        const { code } = data
        if ([110001, 110002].includes(+code)) {
          // token过期，重新获取token并注册
          this.timeoutTimes += 1
          if (this.timeoutTimes < 6) {
            UserStore.queryUserInfo().then(() => {
              this.registerToken()
            })
          }
        }
      })
    }

    if (!this.$socket._callbacks.$project_user_role) {
      this.$socket.on('project_user_role', () => {
        // 有新的消息
        console.log('fetch new message')
        this.queryNoticeListInShortcut()
      })
    }
  }

  /**
   * websocket注册用户登录信息
   */
  registerToken() {
    if (UserStore.loginToken) {
      this.$socket.emit('register', {
        // 注册用户登录信息
        token: UserStore.loginToken,
        message: 'message token',
      })
    }
  }

  public async handleLogout() {
    await UserStore.logout()
    // 清空所有State
    UserStore.clearState()
    DataStore.clearState()
    ProjectStore.clearState()

    this.$router.push('/login')
    this.$message.success('您已退出登录')
  }

  public get unreadNoticeList(): any[] {
    return MessageStore.unreadNoticeList
  }

  public get readNoticeList(): any[] {
    return MessageStore.readNoticeList
  }

  public async handleChange(key: any) {
    await MessageStore.queryNoticeListInShortcut({
      pageNum: 1,
      pageSize: 10,
      status: key, // 0：未读，1.已读
    })
  }

  /**
   * 查看消息
   */
  public readMessage(list: { id: string; projectId: string; status: number }) {
    if (list.status === 0) {
      // 未读消息设置为已读
      MessageStore.processNotice({ ids: [list.id] }).then(() => {
        this.queryNoticeListInShortcut()
      })
    }
    if (list.projectId) {
      const routerUrl = this.$router.resolve(`/project/${list.projectId}/data`)
      window.open(routerUrl.href, '_blank')
    }
  }

  // 确定反馈对话框
  public async handleFeedbackModalOk() {
    // 字数限制
    if (
      this.feedbackTextarea.length < 3 ||
      this.feedbackTextarea.length > 300
    ) {
      this.$message.error('反馈字数太少或超出最大范围')
      return
    }
    const formData = new FormData()
    this.fileList.forEach((file: any) => {
      formData.append('picture', file.originFileObj, file.originFileObj.name)
    })
    const passData = {
      data: formData,
      params: {
        id: UserStore.currentUser?.id,
        feedback: this.feedbackTextarea,
      },
    }
    const result = await saveFeedback(passData)
    if (result.data.code === 100) {
      this.feedbackModalVisible = false
      this.fileList = []
      this.feedbackTextarea = ''
      this.$message.success('提交意见反馈成功！')
      this.resetModalValue()
    }
  }

  // 关闭反馈对话框
  public closeFeedbackModal() {
    this.feedbackModalVisible = false
    this.resetModalValue()
  }

  public handleCancelPreview() {
    this.previewVisible = false
  }

  // 预览图
  public async handlePreview(file: any) {
    if (!file.url && !file.preview) {
      file.preview = await this.getBase64(file.originFileObj)
    }
    this.previewImage = file.url || file.preview
    this.previewVisible = true
  }

  // 改变文件列表
  public handleChangeFileList(options: any) {
    const { fileList } = options
    const newFileList: any = []
    fileList.forEach((file: any) => {
      if (file.status === 'uploading') {
        file.status = 'done'
      }
      if (file.status === 'done') {
        newFileList.push(file)
      }
    })

    if (fileList.length <= 4) {
      this.fileList = newFileList
    } else {
      this.$message.error('图片应该不超过4张')
    }
  }

  // 限制图片类型与大小
  public beforeUpload(file: any) {
    // 前端阻止上传同名文件
    for (let i = 0; i < this.fileList.length; i += 1) {
      if (file.name === this.fileList[i].name) {
        this.$message.error('存在同名文件！')
        return false
      }
    }
    // 限制图片类型
    const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
    if (!isJpgOrPng) {
      this.$message.error('请上传JPG/PNG格式的文件!')
    }
    // 限制图片大小
    const isLt2M = file.size / 1024 / 1024 < 2
    if (!isLt2M) {
      this.$message.error('图片的大小不能超过2MB!')
    }
    return isJpgOrPng && isLt2M
  }

  // 上传图片
  public customRequest() {
    // 不需要做什么
  }

  // file转base64
  public getBase64(file: any) {
    return new Promise((resolve, reject) => {
      const reader = new FileReader()
      reader.readAsDataURL(file)
      reader.addEventListener('load', () => resolve(reader.result))
      reader.addEventListener('error', (error) => reject(error))
    })
  }

  // 解析消息字符串
  public splitMessageContent(message: string) {
    const temporaryMessage = message.split('<b>').filter((item) => item !== '')
    const strongMessageContent: any[] = []
    temporaryMessage.forEach((item) => {
      if (item.includes('</b>')) {
        strongMessageContent.push([item.split('</b>')[0], 1])
        strongMessageContent.push([item.split('</b>')[1], 0])
      } else {
        strongMessageContent.push([item, 0])
      }
    })
    return strongMessageContent
  }

  // 开始新手指引
  public startUserGuide() {
    UserGuideStore.intoGuide()
  }
}
</script>

<style lang="less" scoped>
@import '@/constants';

.icons {
  display: inline-flex;
}

.user-info-container {
  align-items: center;
  cursor: pointer;
  display: flex;
  height: @HEADER_HEIGHT;
  padding: 0 15px;

  .avatar {
    border-radius: 50%;
    font-size: 24px;
    margin-right: 8px;
    overflow: hidden;
    padding: 0;
  }
}

.nickname {
  color: #5d637e;
  font-size: 16px;
  font-weight: 500;
  letter-spacing: 1px;
  line-height: 22px;
  margin-right: auto;
  overflow: hidden;
  white-space: nowrap;
}

.username {
  color: #222432;
  font-size: 12px;
  font-weight: 400;
  line-height: 17px;
  opacity: 0.5;
  overflow: hidden;
  white-space: nowrap;
}

.message-info-container {
  align-items: center;
  cursor: pointer;
  display: flex;
  height: @HEADER_HEIGHT;
  padding: 0 15px;
  vertical-align: middle;

  .message-icon {
    color: #fff;
    font-size: 24px;
    height: 24px;
    width: 24px;
  }
}

.message-list {
  background: #fff;
  border-radius: 2px;
  box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.15);
  height: 415px;
  width: 426px;
}

.tab-panel {
  height: 330px;
  overflow: scroll;

  &::-webkit-scrollbar {
    height: 6px;
    width: 6px;
  }

  &::-webkit-scrollbar-thumb {
    background: rgba(144, 147, 153, 0.5);
    border-radius: 6px;
  }

  &::-webkit-scrollbar-track {
    background: transparent;
    border-radius: 5px;
  }
}

li:hover {
  color: @TEXT_HOVER_COLOR;
}

/deep/ .ant-tabs-tab {
  text-align: center;
  width: 195px;
}

/deep/ .ant-dropdown-menu-item {
  margin: 0 8px;
}

.message-footer {
  background: #fff;
  border-radius: 0 0 2px 2px;
  border-top: 1px solid #eee;
  bottom: 0;
  color: #222432;
  font-size: 12px;
  font-weight: 400;
  height: 40px;
  letter-spacing: 1px;
  line-height: 40px;
  text-align: center;
  vertical-align: middle;
  width: 98%;
}

.notice-btn {
  border: 1px solid #6771ff;
  color: #6973ff;
  font-size: 12px;
  font-weight: 400;
  height: 22px;
  line-height: 22px;
  margin-right: 20px;
  text-align: center;
  width: 42px;
}

.notice-time {
  color: #5d637e;
  font-size: 12px;
  font-weight: 400;
  height: 16px;
  letter-spacing: 1px;
  line-height: 16px;
}

.popover-container {
  right: 0;
}

.drop-icon {
  height: 14px;
  margin-right: 8px;
  width: 14px;
}

/deep/ .ant-popover.ant-popover-placement-bottom {
  right: 0 !important;
  top: 54px !important;
  transform-origin: 40% -10px;
  width: 426px;

  .ant-popover-content {
    .ant-popover-arrow {
      display: none !important;
    }
  }
}

.modal-subtext {
  color: #222432;
  font-size: 12px;
  letter-spacing: 1.12px;
  opacity: 0.5;
}
</style>
